package com.zhudi.model;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.zhudi.commen.ErrorCode;
import com.zhudi.expection.BusinessException;
import com.zhudi.utils.SignatureUtils;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;

@Data
/**
 * client的父类，负责身份校验、
 */
public class AbstractClient {
    public static final String GATE_WAY = "localhost:8081";
    /**
     * 用户的登录凭证
     */
    private Credential credential;
    /**
     * 目标端口
     */

    //endpoint =  service.rootDomain
    private String endpoint;
    //具体端口的别名
    private String service;

    //用于进行http请求
    private HttpConnection httpConnection;
    //用于记录http请求的一些信息
    private HttpProfile httpProfile;


    public AbstractClient() {
    }

    public AbstractClient(Credential credential, String endpoint, String service) {
       this(credential,endpoint,service,new HttpConnection(),new HttpProfile());
    }

    public AbstractClient(Credential credential, String endpoint, String service, HttpConnection httpConnection, HttpProfile httpProfile) {
        this.credential = credential;
        this.endpoint = endpoint;
        this.service = service;
        this.httpConnection = httpConnection;
        this.httpProfile = httpProfile;
    }

    public String doRequest(AbstractModel model, String actionName){
        if(httpConnection==null){
            httpConnection =new HttpConnection();
        }
//        1. 获取用户凭证，使用算法加密，材料包括：用户 ak、sk、时间轴
        String accessKey = credential.getAccessKey();
        String secretKey = credential.getSecretKey();
        if (accessKey==null||secretKey==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"accessKey或secreKey缺失");
        }
        long currentTimeMillis = System.currentTimeMillis();

        String signature = SignatureUtils.signByHmacSHA256(accessKey,secretKey, String.valueOf(currentTimeMillis));
        //最后传给后端的应该是统一的鉴权字符串，包括材料和签名
        String authorization =accessKey+"/"+currentTimeMillis+"/"+signature;
//        2. 根据 client 获取当前 sdk 对应的 host
        String host = this.getEndpoint();
//        3. 获取接口的方法类型、参数
        String reqMethod = model.getMethod();
//        4. 将签名认证、接口信息、host 信息构建成请求头发送给网关
        Map<String,String> headers = new HashMap<>();
        headers.put("Host",host);
        headers.put("authorization",authorization);
        headers.put("X-Action",actionName);
        //5. 拼接url
        String url;
        if(!model.getPath().equals("/")){
            url = HttpProfile.REQ_HTTP +GATE_WAY+model.getPath()+"/"+actionName;
        }else {
            url = HttpProfile.REQ_HTTP +GATE_WAY+model.getPath()+actionName;
        }

        //根据方法类型调用不同的方法
        if (!"GET".equals(reqMethod)&&!"POST".equals(reqMethod)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"只能请求POST或者GET");

        }
        if ("GET".equals(reqMethod)){
            Map<String, Object> customizedParams = BeanUtil.beanToMap(model);
            return httpConnection.doGet(url,customizedParams,headers);
        }else{
            String customizedParams  = JSONUtil.toJsonStr(model);

            return httpConnection.doPost(url,customizedParams,headers);
        }
    }

}
